#ifndef INPUTGESTUREDOUBLETAP_H_INCLUDED
#define INPUTGESTUREDOUBLETAP_H_INCLUDED

#include "InputGestureBasicFingers.h"

#include <map>

namespace tuio

{

class ditdoubletap
{
    public:
    float tstamp;
    float x,y;
};

class TeventNewDoubleTap : public TTEvent <TeventNewDoubleTap>
{
    public:
    float x,y;
};


class InputGestureDoubleTap : public CanBasicFingers< tuioApp <InputGesture> >
{
    public:
    InputGestureBasicFingers * gesturefingers;
    std::map<int,ditdoubletap *> elsdits;
    int32 id_1,id_2;
    int num_fingers;
    bool id1_removed;

    InputGestureDoubleTap()
    {
        gesturefingers = Singleton<InputGestureBasicFingers>::get();
        num_fingers=0;
    }

    virtual void ReceiveCall(const char * addr, osc::ReceivedMessageArgumentStream & argList)
    {
        std::list<TEvent*>::iterator it;
        for(it = gesturefingers->events.begin();
            it != gesturefingers->events.end();
            it++)
        {
            TEvent * e = *it;
            processTevent(e);
        }
    }

    //Interface redefined by ofApp
    void addTuioCursor(int32 id, float xpos,float ypos,float xspeed,float yspeed,float maccel)
    {
        ditdoubletap * d = new ditdoubletap();
        d->tstamp = ofGetElapsedTimef();
        d->x = xpos;
        d->y = ypos;
        elsdits[id] = d;

         if(num_fingers == 0)
        {
            id_1 = id;
            num_fingers++;
            id1_removed = false;
        }
        else if (num_fingers == 1)
        {
            if((elsdits[id]->tstamp - elsdits[id_1]->tstamp) < 0.4)
            {
                id_2 = id;
                num_fingers++;
            }
            else
                id_1 = id;
        }
    }
    void updateTuioCursor(int32 id, float xpos,float ypos,float xspeed,float yspeed,float maccel){}
    void removeTuioCursor(int32 id)
    {
        if (id_1==id)
        {
            id1_removed=true;
        }
        else if (id_2==id)
        {
            if (id1_removed)
            {
                if((elsdits[id_2]->tstamp - elsdits[id_1]->tstamp < 0.4) && (std::abs(elsdits[id_2]->x - elsdits[id_1]->x < 0.02))
                    && (std::abs(elsdits[id_2]->y - elsdits[id_1]->y < 0.02)))
                {
                    TeventNewDoubleTap * evt = new TeventNewDoubleTap();
                    evt->x = elsdits[id]->x;
                    evt->y = elsdits[id]->y;
                    events.push_back(evt);
                }

                id_1 = 0;
                id_2 = 0;
                num_fingers=0;
            }
            else //finger 2 was first removed
            {
                id_1 = 0;
                id_2 = 0;
                num_fingers=0;
            }

        }
    }

};

template<class Base>
class CanDoubleTap : public Base
{
    public:
  ///Interficie
  virtual void newDoubletap(double x, double y){}

  ///Handlers
  TEventHandler(TeventNewDoubleTap)
  {
      TeventNewDoubleTap * e = static_cast<TeventNewDoubleTap *>(evt);
      newDoubletap(e->x,e->y);
  }

  ///Register
  CanDoubleTap()
  {
      TRegistraCallback(CanDoubleTap,TeventNewDoubleTap);
      registerMeToInputGestureManager(Singleton<InputGestureDoubleTap>::get());
  }

    eventprocessorsType & getEP()
    {
        return Base::getEP();
    }

};

}


#endif // INPUTGESTUREDOUBLETAP_H_INCLUDED
